﻿#pragma once
namespace LK
{
	namespace Collection
	{
		template<class T>struct Vector :public IArray<T>
		{
		public:
			typedef ptr<Vector<T>> xArray;
			BMETHODS(xArray, Vector)
				static void AddTypeInfo();
			//内置std::vector成员
				std::vector<T> data;
			/**
			@brief 返回一个浅表副本*/
			Vector* Clone()const { return new Vector(*this); }
			/**
			@brief 获取元素数*/
			index_t size()const { return data.size(); }
			/**
			@brief 获取数组当前最大容量
			@note 当数组元素数不大于最大容量，而且两者之差不大于MaxUnusedLength时，对象存储区域将不会进行内存的重新调整*/
			index_t GetMaxSize()const { return data.capacity(); }
			/**
			@brief 长度检查，len为负将抛出异常*/
			static void CheckLength(index_t len) { if (len < 0)Throw<PInvalidArgumentException>(L"数组长度不可以为负值"); }
			/**
			@brief 获取数组内容首地址*/
			virtual void const* GetData()const { return data.size() == 0 ? (void const*)NULL : &data[0]; }
			/**
			@brief 调整大小，返回调整后数组元素最大大小
			@note 如果len<0将抛出异常*/
			index_t Resize(index_t len)
			{
				CheckLength(len);
				data.resize(len);
				return data.capacity();
			}
			/**
			@brief 默认构造函数，构造一个空Vector数组*/
			Vector() :data() { }
			/**
			@brief 传入数组长度，构造一个未初始化的数组
			@note 当指定数组长度length小于0时，将抛出异常*/
			Vector(index_t length) :data()
			{
				CheckLength(length);
				data.resize(length);
			}
			/**
			@brief 复制构造函数
			@note 新数组的类型将是Vector*/
			Vector(const Vector&vfa) :data(vfa.data) {}
			/**
			@brief 构造函数，从std::vector构造
			@note 新数组的类型将是Vector*/
			Vector(const std::vector<T>&vfa) :data(vfa) {}
#ifdef SUPPORT_RIGHT_VALUE_REFERENCE
			/**
			@brief 构造函数，从std::vector构造
			@note 新数组的类型将是Vector*/
			Vector(std::vector<T>&&vfa) : data(vfa) {}
#endif
#ifdef _INITIALIZER_LIST_//初始化列表支持
			Vector(std::initializer_list<T> const& lst) :data(lst)
			{
			}
#endif	
			/**
			@brief 构造函数
			@note 新数组的类型将是Vector*/
			Vector(const IArray<T>&vfa) :data(vfa.begin(), vfa.end())
			{
			}
			/**
			@brief 传入数组元素，并使用一个参考元素来初始化所有元素
			@param [传入]参数len表示数组元素数
			@param [传入]参数t为参考元素
			@note 当指定数组长度len小于0时，将抛出异常*/
			Vector(index_t len, const T&t)
			{
				CheckLength(len);
				data.resize(len);
				for (index_t i = 0; i < len; ++i)data[i] = t;
			}
			/**
			@brief 使用迭代器构造，如果迭代器所表示内容多于MaxSize，则只取前MaxSize个内容来构造
			@note 迭代器类型必须要通过typedef或者using定义value_type成员*/
			template<class IT>Vector(const IT&first, const IT&end, typename UseIf<IsConvertible<typename IT::value_type, T>::V>::T*p = NULL) :data(first, end)
			{
			}
			/**
			@brief 直接传入元素数和指针来构造数组
			@param [传入]参数len用以指定元素数
			@param [传入]参数p指向存放空间
			@note 若len<0或len>MaxSize将抛出异常，如果p为NULL进行默认初始化*/
			Vector(index_t len, const T*p) :data()
			{
				CheckLength(len);
				data.resize(len);
				for (index_t i = 0; i < len; ++i)
					data[i] = *p++;
			}
			/**
			@brief 从C-Style数组进行复制构造*/
			template<class TT>Vector(const TT&arr, typename UseIf<IsArray<TT>::V>::T*p = NULL) : data()
			{
				data.resize(IsArray<TT>::C);
				for (index_t i = 0; i != IsArray<TT>::C; ++i)data[i] = arr[i];
			}
		};
	}
}
